package edu.ruc.cluster.ui;

import java.awt.Color;
import java.awt.Font;
import java.awt.GridLayout;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.IOException;

import javax.swing.BoxLayout;
import javax.swing.ImageIcon;
import javax.swing.JLabel;
import javax.swing.JTextField;
import javax.swing.JPasswordField;
import javax.swing.JPanel;

import edu.ruc.cluster.util.ColumnLayout;
import edu.ruc.cluster.util.Const;
import edu.ruc.cluster.util.DefaultLogHandler;
import edu.ruc.cluster.util.ImageLabel;
import edu.ruc.cluster.util.PropertyRetrieval;

@SuppressWarnings("serial")
public class HadoopUserLoginPane extends JPanel {

	private DefaultLogHandler logHandler = null;
	private JPanel userPane = null;		
	private JTextField username = null;
	private JPasswordField passwd = null;
	private JLabel namecheck = null;
	private JLabel passwdcheck = null;
		
	private JPanel sudoPane = null;
	private JTextField sudouser = null;
	private JPasswordField sudopasswd = null;
	private JLabel snamecheck = null;
	private JLabel spasswdcheck = null;
	
	private boolean readyForNext = false;
	
	public HadoopUserLoginPane(){
	}
	public void constructPane(){
		logHandler = DefaultLogHandler.getInstance();
		setupLoginPanel();
		setupSudoPane();
		
		setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
		this.add(userPane);
		this.add(sudoPane);
		this.setVisible(true);
	}
	private void setupSudoPane(){
		sudoPane = new JPanel(new ColumnLayout());
		JLabel caption = new JLabel("<html>please input the sudoer's username and password " +
				"for the machine you run this program</html>");
		caption.setFont(new Font("SansSerif.bold", Font.ITALIC, 16));
		caption.setForeground(Color.RED);
		
		JLabel nameLabel = new JLabel("Username");
		JLabel passwdLabel = new JLabel("Password");
		nameLabel.setFont(new Font(Const.LABEL_FONT, Font.PLAIN, 14));
		passwdLabel.setFont(new Font(Const.LABEL_FONT, Font.PLAIN, 14));
		
		sudouser = new JTextField();
		sudopasswd = new JPasswordField();
		
		snamecheck = new JLabel("");
		spasswdcheck = new JLabel("");
		
		JPanel tmp = new JPanel();
		tmp.setLayout(new GridLayout(2, 3, 20, 5));
		tmp.add(nameLabel);
		tmp.add(sudouser);
		tmp.add(snamecheck);
		tmp.add(passwdLabel);
		tmp.add(sudopasswd);
		tmp.add(spasswdcheck);
		
		sudoPane.add(caption);
		sudoPane.add(tmp);		
	}
	
	private void setupLoginPanel(){
		userPane = new JPanel(new ColumnLayout());
		JLabel caption = new JLabel("<html>please input the username and password " +
				"for running hadoop</html>");
		caption.setFont(new Font("SansSerif.bold", Font.ITALIC, 16));
		caption.setForeground(Color.RED);
		
		JLabel nameLabel = new JLabel("Username");
		JLabel passwdLabel = new JLabel("Password");
		nameLabel.setFont(new Font(Const.LABEL_FONT, Font.PLAIN, 14));
		passwdLabel.setFont(new Font(Const.LABEL_FONT, Font.PLAIN, 14));
		
		username = new JTextField();
		passwd = new JPasswordField();
		
		namecheck = new JLabel("");
		passwdcheck = new JLabel("");
		
		JPanel tmp = new JPanel();
		tmp.setLayout(new GridLayout(2, 3, 20, 5));
		tmp.add(nameLabel);
		tmp.add(username);
		tmp.add(namecheck);
		tmp.add(passwdLabel);
		tmp.add(passwd);
		tmp.add(passwdcheck);
		
		userPane.add(caption);
		userPane.add(tmp);
		
	}
	
	private void checkInput(){
		
		ImageIcon ok = new ImageIcon(getClass().getResource(Const.RIGHT_ICON_PATH), "right icon");
		ImageIcon error = new ImageIcon(getClass().getResource(Const.WRONG_ICON_PATH), "wrong icon");
		
		namecheck = username.getText().isEmpty() ? new ImageLabel(error) : new ImageLabel(ok);
		passwdcheck = String.valueOf(passwd.getPassword()).isEmpty() ? new ImageLabel(error) : new ImageLabel(ok);
		snamecheck = sudouser.getText().isEmpty() ? new ImageLabel(error) : new ImageLabel(ok);
		spasswdcheck = String.valueOf(sudopasswd.getPassword()).isEmpty() ? new ImageLabel(error) : new ImageLabel(ok);

		/**
		 * I quite not sure if we can use getIcon().equals() method to tell whether is ok or not
		 */
		if(namecheck.getIcon().equals(ok) && passwdcheck.getIcon().equals(ok)
				&& snamecheck.getIcon().equals(ok) && spasswdcheck.getIcon().equals(ok))
			readyForNext = true;
		
		this.updateUI();
	}
	
	public void store(){
		// TO-DO: Add hadoop user and localhost user to Const.CONFIG_FILE
			
		PropertyRetrieval pr = new PropertyRetrieval(Const.CONFIG_FILE, true);
		logHandler.info("store localhost user and passwd to " + Const.CONFIG_FILE);
		pr.putString(Const.LOCALHOST_TAG, sudouser.getText().toString().trim());
		logHandler.info("store hadoop user and passwd to " + Const.CONFIG_FILE);
		pr.putString(Const.HADOOP_USER_TAG, username.getText().toString().trim());
		
		try{
			System.out.println("update store called");
			BufferedReader reader = new BufferedReader(new FileReader(new File(Const.USER_PW_FILE)));
			String line = null;
			StringBuffer buffer = new StringBuffer();
			String localUser = Const.LOCALHOST_TAG + Const.LINE_SEPERATOR 
							+ sudouser.getText().toString().trim() + Const.LINE_SEPERATOR
							+ String.valueOf(sudopasswd.getPassword()).trim() + "\n";
			String hadoopUser = Const.HADOOP_USER_TAG + Const.LINE_SEPERATOR
							+ username.getText().toString().trim() + Const.LINE_SEPERATOR
							+ String.valueOf(passwd.getPassword()).trim() + "\n";
			
			boolean append1 = true;
			boolean append2 = true;
			while((line = reader.readLine()) != null){
				// If corresponding content exists, change it
				if(line.contains(Const.LOCALHOST_TAG) == true){
					buffer.append(localUser);
					append1 = false;
				}
				else if(line.contains(Const.HADOOP_USER_TAG) == true){
					buffer.append(hadoopUser);
					append2 = false;
				}
				else 
					buffer.append(line + "\n");
			}
				// If the content do not exist, append it
			if(append1 ==  true)
				buffer.append(localUser);
			if(append2 == true)
				buffer.append(hadoopUser);
			
			reader.close();
			
			BufferedWriter writor = new BufferedWriter(new FileWriter(new File(Const.USER_PW_FILE)));
			writor.write(buffer.toString());
			writor.close();
			logHandler.info("finished store in " + this.getClass().getName());
			
		}catch(FileNotFoundException e){
			logHandler.error(this.getClass().getSimpleName() + e.getMessage(), e);
		}catch(IOException e){
			logHandler.error(this.getClass().getSimpleName() + e.getMessage(), e);
		}
		
		
	}
	public boolean ok(){
		checkInput();
		return readyForNext;
	}
	
}
